package org.cqipc.edu.config;

import at.pollux.thymeleaf.shiro.dialect.ShiroDialect;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.CookieRememberMeManager;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.apache.shiro.web.servlet.SimpleCookie;
import org.cqipc.edu.realm.RoleRealm;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.handler.SimpleMappingExceptionResolver;

import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Properties;

/**
 * @Description:Shiro配置
 * @ClassName: ShiroConfig
 * @Author: Heyue
 * @DateTime: 2020-06-22
 **/
@Configuration
public class ShiroConfig {


    /**
     * @Description: 获取自定义Realm类
     * @Author: Heyue
     * @Date: 2020/6/22
     */
    @Bean(name = "RoleRealm")
    public RoleRealm getRoleRealm() {
        return new RoleRealm();
    }


    /**
     * @Description: 设置Shiro安全管理器
     * @Author: Heyue
     * @Date: 2020/6/22
     */
    @Bean(name = "securityManager")
    public DefaultWebSecurityManager getDefaultWebSecurityManager(@Qualifier("RoleRealm") RoleRealm roleRealm) {
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        securityManager.setRealm(roleRealm);

        return securityManager;
    }


    /**
     * @Description: 创建Shiro过滤器工厂Bean
     * @Author: Heyue
     * @Date: 2020/6/22
     */
    @Bean
    public ShiroFilterFactoryBean getShiroFilterFactoryBean(@Qualifier("securityManager") DefaultWebSecurityManager defaultWebSecurityManager) {
        ShiroFilterFactoryBean bean = new ShiroFilterFactoryBean();

        //设置安全管理器
        bean.setSecurityManager(defaultWebSecurityManager);

        //未授权时跳转到登陆页面
        bean.setLoginUrl("/login");
        //登陆成功后跳转的页面
        bean.setSuccessUrl("/index");
        //没有授权时跳转到此页面
        bean.setUnauthorizedUrl("/403");

        Map<String, String> filterMap = new LinkedHashMap<>();
        /**
         *==添加shiro内置过滤器==
         * anon：无需认证可访问
         * authc：必须认证才能访问
         * user：必须拥有记住我功能才可使用
         * perms：拥有对某个资源的权限
         * role：拥有某个角色权限下能访问
         */
        //放行登录校验接口
        filterMap.put("/checkLogin", "anon");
        //只要设置了记住我就可以直接访问
        filterMap.put("/index", "user");
        //设置授权(登录)之前所有接口不可访问
        filterMap.put("/*", "authc");

        bean.setFilterChainDefinitionMap(filterMap);
        return bean;
    }


    /**
     * @Description: 开启对shior注解的支持
     * @Author: Heyue
     * @Date: 2020/7/2
     */
    @Bean
    public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager) {
        AuthorizationAttributeSourceAdvisor advisor = new AuthorizationAttributeSourceAdvisor();
        advisor.setSecurityManager(securityManager);
        return advisor;
    }


    /**
     * @Description: Thymeleaf整合Shiro
     * @Author: Heyue
     * @Date: 2020/6/22
     */
    @Bean
    public ShiroDialect getShiroDialect() {
        return new ShiroDialect();
    }


    /**
     * @Description: 未授权页面跳转配置
     * @Author: Heyue
     * @Date: 2020/7/2
     */
    @Bean
    public SimpleMappingExceptionResolver simpleMappingExceptionResolver() {
        SimpleMappingExceptionResolver resolver = new SimpleMappingExceptionResolver();
        Properties properties = new Properties();
        properties.setProperty("org.apache.shiro.authz.UnauthorizedException", "redirect:/403");
        resolver.setExceptionMappings(properties);
        return resolver;
    }


    /**
     * @Description: Cookie对象
     * @Author: Heyue
     * @Date: 2020/7/2
     */
    @Bean
    public SimpleCookie rememberMeCookie() {
        //这个参数是cookie的名称，对应前端的checkbox的name = rememberMe
        SimpleCookie simpleCookie = new SimpleCookie("rememberMe");
        //设置记住我功能的cookie生效时间为2分钟(用于测试)
        simpleCookie.setMaxAge(120);
        return simpleCookie;
    }


    /**
     * @Description: cookie管理对象
     * @Author: Heyue
     * @Date: 2020/7/2
     */
    @Bean
    public CookieRememberMeManager cookieRememberMeManager() {
        CookieRememberMeManager manager = new CookieRememberMeManager();
        manager.setCookie(rememberMeCookie());
        return manager;
    }

}
